package com.learn.io.netty;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.util.CharsetUtil;
import io.netty.util.concurrent.EventExecutorGroup;
import io.netty.util.concurrent.GlobalEventExecutor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 自定义Netty的Handler需要继承规定好的HandlerAdapter
 * @author wangxing
 * @version 2020/7/30 10:08 Administrator
 */
public class MyNettyServerHandler extends ChannelInboundHandlerAdapter {
    private static ChannelGroup channelGroup = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);

    Logger logger = LoggerFactory.getLogger(MyNettyServerHandler.class);
    /**
     * 读取客户端发送的请求
     * @param ctx 上下文对象,含有通道channel,管道pipeline
     * @param msg 客户端发送的数据
     * @throws Exception
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        logger.info("服务端读取线程name:{},id:{}",Thread.currentThread().getName(),Thread.currentThread().getId());
        Channel channel = ctx.channel();
        channelGroup.add(channel);
        logger.info("--------------{}上线了-----------",channel.remoteAddress());
        ByteBuf buf = (ByteBuf) msg;
        logger.info("客户端发送的消息是:{}",buf.toString(CharsetUtil.UTF_8));
    }


    /**
     * 数据读取完毕处理方法
     *
     * @param ctx
     */
    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        String message = "Hello Netty Client";
        ByteBuf buf = Unpooled.copiedBuffer(message.getBytes());
        ctx.writeAndFlush(buf);
        logger.info(message);
    }

    /**
     * Calls {@link ChannelHandlerContext#fireChannelWritabilityChanged()} to forward
     * <p>
     * Sub-classes may override this method to change behavior.
     *
     * @param ctx
     */
    @Override
    public void channelWritabilityChanged(ChannelHandlerContext ctx) throws Exception {
        super.channelWritabilityChanged(ctx);
    }

    /**
     *异常处理机制
     * @param ctx
     * @param cause
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        ctx.close();
    }
}
